package cn.jja8.bukkit.bukkitwindowtool.window;

import cn.jja8.bukkit.bukkitwindowtool.window.error.FlushNoWorked;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;

/**
 * 一个菜单界面
 * */
public class MenuWindow implements Window {
    protected final Button[] buttons;
    protected String name;
    Inventory inventory;

    public MenuWindow(String name) {
        buttons = new Button[54];
        this.name = name;
    }
    public MenuWindow(int size,String name) {
        this.name = name;
        if (size%9!=0 || size<9){
            throw new Error("size%9!=0 || size<9");
        }
        buttons = new Button[size];
    }

    /**
     * 设置指定位置的按钮
     * @param sort 按钮的位置
     * @return 在这个位置的上一个按钮，如果没有则返回null
     * */
    public Button setButton(Button button,int sort){
        if (sort<0 || sort>= buttons.length){
            throw new IndexOutOfBoundsException("sort不在界面范围内！");
        }
        Button last = buttons[sort];
        try {
            if (last!=null){
                last.beReplaced(button);
            }
        }catch (Throwable throwable){
            throwable.printStackTrace();
        }

        buttons[sort] = button;
        try {
            if (button!=null){
                button.beAdd(this,new ListFlushWork(button,sort));
            }
        }catch (Throwable throwable){
            throwable.printStackTrace();
        }
        flush(sort);
        return last;
    }
    /**
     * 删除某位置的按钮
     * */
    public Button removeButton(int sort){
        return setButton(null,sort);
    }


    /**
     * 刷新某位置的按钮
     * */
    private void flush(int sort) {
        if (inventory==null){
            return;
        }
        ItemStack itemStack = null;
        if (buttons[sort] != null) {
            try {
                itemStack = buttons[sort].getItemStack();
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }

        }
        inventory.setItem(sort, itemStack);
    }

    @Override
    public Inventory getInventory() {
        if (inventory==null){
            inventory = Bukkit.createInventory(null,buttons.length,name==null?"NULL":name);
            for (int i = 0; i < buttons.length; i++) {
                flush(i);
            }
        }
        return inventory;
    }

    @Override
    public void click(InventoryClickEvent inventoryClickEvent, Player player) {
        int chick = inventoryClickEvent.getRawSlot();
        if (chick<0||chick>=buttons.length){
            inventoryClickEvent.setCancelled(true);
            return;
        }
        if (buttons[chick]==null){
            inventoryClickEvent.setCancelled(true);
            return;
        }
        try {
            buttons[chick].click(inventoryClickEvent,player);
        }catch (Throwable throwable){
            throwable.printStackTrace();
        }
    }

    class ListFlushWork implements FlushWork{
       private final  Button button;
       private final int sort;

        public ListFlushWork(Button button, int sort) {
            this.button = button;
            this.sort = sort;
        }

        /**
         * 调用此方法后窗口会重新调用按钮的getItemStack方法刷新显示的物品。
         */
        @Override
        public void flush() {
            if (buttons[sort]!=button) {
                throw new FlushNoWorked("刷新器已失效！");
            }
            MenuWindow.this.flush(sort);
        }
    }
}
